package decorator;

/**
 * 装饰者模式：允许动态地向一个现有的对象添加新的功能，同时不改变其结构，相当于对现有对象进行包装
 * 1. 装饰对象和真实对象有相同的接口，能够以相同的方式对真实对象和装饰对象交互
 * 2. 装饰对象中有一个真实对象的引用
 * 3. 装饰对象接收所有请求，转发给真实对象
 * 4. 装饰对象能在转发请求前后附加一些功能
 * 即适用于一个通用功能扩展但又不想继承原有类
 *
 * 组成：
 * 1. 抽象组件Component类
 * 2. 组件具体实现类ConcreatComponent类，即被装饰的对象
 * 3. 抽象装饰类Decorator，内部持有一个组件对象的引用
 * 4. 具体装饰类ConcreatDecorator
 *
 * =>
 *  new BufferReader(new FileReader("file"))
 *  mybatis中BaseExecutor中存放一级缓存，对默认实现PerpetualCache不断装饰
 *
 *  优点：
 *  灵活，装饰者不同排列可实现不同效果，遵循开闭原则
 *  缺点：
 *  更多代码更多类，多层装饰比较复杂
 */
public class DecoratorTest {

    public static void main(String[] args) {
        //普通蛋糕
        Cake cake = new BaseCake();
        System.out.println(cake);
        //加芒果
        cake = new CakeAddMangoDecorator(cake);
        System.out.println(cake);
        //再加葡萄
        cake = new CakeAddGrapeDecorator(cake);
        System.out.println(cake);
        //再加一个芒果
        cake = new CakeAddMangoDecorator(cake);
        System.out.println(cake);

    }

}
